﻿using System;
using ScrappyDB.Attributes;
using NUnit.Framework;
using ScrappyDB.BaseClasses;

namespace ScrappyDB.IntegrationTests.Core
{


    /// <summary>
    ///This is a test class for AlternatePropertyNameAttributeTest and is intended
    ///to contain all AlternatePropertyNameAttributeTest Unit Tests
    ///</summary>
    [TestFixture]
    public class AlternatePropertyNameAttributeTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes

        
        //Use ClassCleanup to run code after all tests in a class have run
        [TestFixtureTearDown]
        public static void MyClassCleanup()
        {
            var db = new Db();
            var entity1 = db.Query<Entity1>(true);
            db.Delete<Entity1>(entity1);

            var entity2 = db.Query<Entity2>(true);
            db.Delete<Entity1>(entity2);

            var entity3 = db.Query<Entity3>(true);
            db.Delete<Entity1>(entity3);

            var entityGuidIdTest = db.Query<EntityGuidIdTest>(true);
            db.Delete<Entity1>(entityGuidIdTest);

            var entityDateTimeIdTest = db.Query<EntityDateTimeIdTest>(true);
            db.Delete<Entity1>(entityDateTimeIdTest);

        }
        
        //Use TestInitialize to run code before running each test
        //[SetUp]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TearDown]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        [Test]
        public void AlternatePropertyNameAttributeTestSingleValue()
        {
            var db = new Db();
            //create a record and save it with
            var a = new Entity1() { Id = 1, Value1 = "Test" };
            db.SaveChanges(a);

            //try to load the same record using a different entity definition that uses AlternateProperyName
            var b = db.Find<Entity2>(1);

            Assert.AreEqual(a.Value1, b.Value2);
        }

        [Test]
        public void AlternatePropertyNameAttributeTestMultiValue()
        {
            var db = new Db();
            //create a record and save it with
            var a = new Entity1() { Id = 1, Value1 = "Test1" };
            db.SaveChanges(a);

            var b = new Entity3() { Id = 2, Value3 = "Test3" };
            db.SaveChanges(b);

            //try to load the same record using a different entity definition that uses AlternateProperyName
            var c = db.Find<Entity2>(1);
            Assert.AreEqual(a.Value1, c.Value2);

            var d = db.Find<Entity2>(2);
            Assert.AreEqual(b.Value3, d.Value2);
        }

        [Test]
        public void IntegerIdPropertyTest()
        {
            var db = new Db();
            //create a record and save it with
            var a = new Entity1() { Id = 1, Value1 = "Test" };
            db.SaveChanges(a);

            //try to load the same record using a different entity definition that uses AlternateProperyName
            var b = db.Find<Entity1>(1);

            Assert.AreEqual(a.Value1, b.Value1);
        }

        [Test]
        public void GuidIdPropertyTest()
        {
            var db = new Db();
            //create a record and save it with
            var a = new EntityGuidIdTest() { Id = Guid.Empty, Value = "Test" };
            db.SaveChanges(a);

            //try to load the same record using a different entity definition that uses AlternateProperyName
            var b = db.Find<EntityGuidIdTest>(Guid.Empty);

            Assert.AreEqual(a.Value, b.Value);
        }

        [Test]
        public void DateTimeIdPropertyTest()
        {
            var db = new Db();
            //create a record and save it with
            var a = new EntityDateTimeIdTest() { Id = DateTime.MinValue, Value = "Test" };
            db.SaveChanges(a);

            //try to load the same record using a different entity definition that uses AlternateProperyName
            var b = db.Find<EntityDateTimeIdTest>(DateTime.MinValue);

            Assert.AreEqual(a.Value, b.Value);
        }


    }

    [DomainName("ScrappyDB_UnitTests"), EntityName("AlternatePropertyTest")]
    public class Entity1 
    {
        public int Id { get; set; }
        public string Value1 { get; set; }
    }

    [DomainName("ScrappyDB_UnitTests"), EntityName("AlternatePropertyTest")]
    public class Entity3 
    {
        public int Id { get; set; }
        public string Value3 { get; set; }
    }

    [DomainName("ScrappyDB_UnitTests"), EntityName("AlternatePropertyTest")]
    public class Entity2 
    {
        public int Id { get; set; }

        [AlternatePropertyName("Value1"),AlternatePropertyName("Value3")]
        public string Value2 { get; set; }
    }

    [DomainName("ScrappyDB_UnitTests"), EntityName("AlternatePropertyTest")]
    public class EntityGuidIdTest 
    {
        public Guid Id { get; set; }

        public string Value { get; set; }
    }

    [DomainName("ScrappyDB_UnitTests"), EntityName("AlternatePropertyTest")]
    public class EntityDateTimeIdTest 
    {
        public DateTime Id { get; set; }

        public string Value { get; set; }
    }
}
